package com.zhuang.jdk8.methodreference;

import java.sql.Date;
import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class MethodReference {
	public static void main(String[] args) {
		// test01();
		// test02();
		// test03();
		// test04();
		test05();
		// printMax(MethodReference::getMax);
	}

	public static void getMax(int[] arr) {
		int sum = 0;
		for (int n : arr) {
			sum += n;
		}
		System.out.println(sum);
	}

	private static void printMax(Consumer<int[]> consumer) {
		int[] arr = { 10, 20, 30, 40, 50 };
		consumer.accept(arr);
	}

	// 如果一个类中已经存在了一个成员方法，则可以通过对象名引用成员方法，代 码为：
	public static void test01() {
		Date now = new Date(new Long(166901604));
		Supplier<Long> supp = () -> {
			return now.getTime();
		};
		System.out.println(supp.get());
		Supplier<Long> supp2 = now::getTime;
		System.out.println(supp2.get());
	}

	public static void test02() {
		Supplier<Long> supp = () -> {
			return System.currentTimeMillis();
		};
		System.out.println(supp.get());
		Supplier<Long> supp2 = System::currentTimeMillis;
		System.out.println(supp2.get());
	}

	// Java面向对象中，类名只能调用静态方法，类名引用实例方法是有前提的，实际上是拿第一个参数作为方法的调用 者
	public static void test03() {
		Function<String, Integer> f1 = (s) -> {
			return s.length();
		};
		System.out.println(f1.apply("abc"));
		Function<String, Integer> f2 = String::length;
		System.out.println(f2.apply("abc"));
		BiFunction<String, Integer, String> bif = String::substring;
		String hello = bif.apply("hello", 2);
		System.out.println("hello = " + hello);
	}

	// 由于构造器的名称与类名完全一样。所以构造器引用使用 类名称::new 的格式表示
	public static void test04() {
		Supplier<Person> sup = () -> {
			return new Person();
		};
		System.out.println(sup.get());
		Supplier<Person> sup2 = Person::new;
		System.out.println(sup2.get());
		BiFunction<String, Integer, Person> fun2 = Person::new;
		System.out.println(fun2.apply("张三", 18));
	}

	// 数组也是 Object 的子类对象，所以同样具有构造器，只是语法稍有不同
	public static void test05() {
		Function<Integer, String[]> fun = (len) -> {
			return new String[len];
		};
		String[] arr1 = fun.apply(10);
		System.out.println(Arrays.toString(arr1) + ", " + arr1.length);
		Function<Integer, String[]> fun2 = String[]::new;
		String[] arr2 = fun2.apply(5);
		System.out.println(Arrays.toString(arr2) + ", " + arr2.length);
	}
}
